package system;

import org.apache.log4j.Logger;
import utils.Buffer;
import utils.CommandUtils;
import utils.Consts;
import utils.UserUtils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Scanner;

/**
 * 文件系统对象
 *
 * @author waxijiang
 */
public class FileSystem {
    /**
     * 日志
     */
    static Logger logger = Logger.getLogger(FileSystem.class);

    /**
     * 磁盘对象
     */
    private final Disk disk;

    /**
     * 位图
     */
    private Disk.Bitmap bitmap;

    /**
     * 超级块
     */
    private Disk.SuperBlock superBlock;

    /**
     * inode块
     */
    private Disk.InodeBlock inodeBlock;

    /**
     * 根目录
     */
    private FileItem root;

    /**
     * 当前登陆用户名
     */
    private String user;

    /**
     * 当前路径
     */
    private String currentPath;

    /**
     * 当前目录
     */
    private FileItem currentDir;

    /**
     * 上次访问目录
     */
    private FileItem lastDir;

    /**
     * 内存
     */
    private List<FileItem> memory;

    /**
     * 内存大小
     */
    private int memorySize = 4;

    public FileSystem() {
        logger.info("文件系统初始化");
        disk = Disk.load();
        if (disk == null){
            System.out.println("初始化错误,装载磁盘失败!");
            System.exit(-1);
        }
        superBlock = disk.getSuperBlock();
        bitmap = disk.getBitmap();
        inodeBlock = disk.getInodeBlock();

        this.memory = new ArrayList<FileItem>();
        root = disk.getRoot();
        // 设置默认当前目录
        this.currentPath = "/";
        cd("/");
        logger.info("文件系统初始化完成");
    }

    public Disk.SuperBlock getSuperBlock() {
        return superBlock;
    }

    /**
     * <b>创建新的文件项</b>
     * <br>1. 获取空块
     * <br>2. 创建新文件项
     * <br>3. 将该块标志为占用, 返回文件项
     *
     * @param filename 文件名
     * @param fileType 文件类型
     * @return FileItem对象，如果创建失败则返回null
     */
    public FileItem createNewFileItem(String filename, String fileType) {
        int availableBlockIndex = bitmap.getAvailableBlockIndex();
        if (availableBlockIndex != -1) {
            FileItem fileItem = new FileItem(filename, fileType, Consts.FILE_ITEM_STD_SIZE, Consts.READ_AND_WRITE,
                    Consts.ONLY_READ, new Date(), new Date(), this.user, availableBlockIndex, this.inodeBlock);
            bitmap.use(availableBlockIndex);
            return fileItem;
        } else {
            return null;
        }
    }

    /**
     * 使用inode来创建一个文件,该文件是inode对应文件的一个链接
     *
     * @param filename 文件名
     * @param inode    inode对象
     * @return 创建的文件对象, 如果空间不够则返回null
     */
    public FileItem createNewFileItem(String filename, Disk.Inode inode) {
        int availableBlockIndex = bitmap.getAvailableBlockIndex();
        if (availableBlockIndex != -1) {
            bitmap.use(availableBlockIndex);
            return new FileItem(filename, inode);
        } else {
            return null;
        }
    }

    /**
     * 将要被挂载的文件项挂载到目标目录
     *
     * @param targetDir       要挂载到的目录
     * @param mountedFileItem 要被挂载的文件项
     * @return 是否成功
     */
    public boolean mountFileItem(FileItem targetDir, FileItem mountedFileItem, int mountedFileItemSize) {
        //获取挂载的目录的最后一个文件块
        int lastBlockIndex = targetDir.getInode().getLastBlockIndex();
        Disk.FileBlock fileBlock = disk.getFileBlock(lastBlockIndex);
        // 获取文件块内容
        Object content = fileBlock.getContent();
        int size = fileBlock.getSize();
        // 如果一个文件块可以完全存储
        if (size + mountedFileItemSize < Disk.SuperBlock.FILE_BLOCK_MAX_VOLUME) {
            // 因为要挂载的肯定是目录，目录理应就是List结构
            if (content instanceof List) {
                List<FileItem> fileItem = (List<FileItem>) content;
                fileItem.add(mountedFileItem);
                fileBlock.setContent(fileItem, size + mountedFileItemSize);
                return true;
                // 如果是空目录
            } else if (content == null) {
                List<FileItem> fileItems = new ArrayList<FileItem>();
                fileItems.add(mountedFileItem);
                fileBlock.setContent(fileItems, mountedFileItemSize);
                return true;
            } else {
                // 发生甚么事了？
                System.out.println("???");
                return false;
            }
            //如果一个文件块无法完成存储，寻找新文件块。
        } else if (mountedFileItemSize < Disk.SuperBlock.FILE_BLOCK_MAX_VOLUME) {
            int availableBlockIndex = this.bitmap.getAvailableBlockIndex();
            if (availableBlockIndex != -1) {
                targetDir.getInode().fileBlockIndex.add(availableBlockIndex);
                Disk.FileBlock fileBlock1 = disk.getFileBlock(availableBlockIndex);
                List<FileItem> fileItem = new ArrayList<FileItem>();
                fileItem.add(mountedFileItem);
                fileBlock1.setContent(fileItem, mountedFileItemSize);
                return true;
            } else {
                Buffer.getInstance().write("disk has not enough file block to store!");
                return false;
            }
        } else {
            Buffer.getInstance().write("your file is too big to store!");
            return false;
        }
    }

    /**
     * 解除文件的挂载
     *
     * @param targetDir         要取消挂载的目录
     * @param unmountedFileItem 要取消挂载的文件
     * @return 是否成功
     */
    public boolean unmountFileItem(FileItem targetDir, FileItem unmountedFileItem) {
        List<Integer> fileBlockIndex = targetDir.getInode().fileBlockIndex;
        for (int index : fileBlockIndex) {
            Disk.FileBlock fileBlock = disk.getFileBlock(index);
            // 获取文件块内容
            Object content = fileBlock.getContent();
            int size = fileBlock.getSize();
            if (content instanceof List) {
                List<FileItem> fileItem = (List<FileItem>) content;
                if (fileItem.remove(unmountedFileItem)) {
                    fileBlock.setContent(fileItem, size - unmountedFileItem.getSize());
                    return true;
                } else {
                    return false;
                }
                // 如果是空目录
            } else if (content == null) {
                return false;
            } else {
                // 发生甚么事了？
                System.out.println("???");
                return false;
            }
        }
        return false;
    }

    /**
     * 打印欢迎语句
     */
    public void printWelcome() {
        Buffer.getInstance().write(superBlock.getWELCOME_MEG());
        Buffer.getInstance().output();
    }

    /**
     * 打印命令行提示头
     */
    public void printHint() {
        System.out.print(user + "@localhost:" + currentPath + " $ ");
    }

    /**
     * 登陆
     */
    public boolean login() {
        System.out.print("Login(username):");
        Scanner scanner = new Scanner(System.in);
        String username = scanner.nextLine();
        System.out.print("password:");
        String password = scanner.nextLine();

        if (UserUtils.login(username, password, this.superBlock.getUSER_FILE_LOCATION())) {
            this.user = username;
            // 将当前目录置为用户目录
            cd(username);

            return true;
        } else {
            Buffer.getInstance().write("username or password error!\n");
            Buffer.getInstance().output();
            return false;
        }
    }

    /**
     * 复制fileItem为一个新的fileItem
     * @param fileItem 要被复制的文件对象
     * @return 复制好的文件对象
     */
    public FileItem copyFileItem(FileItem fileItem){
        FileItem newFileItem = createNewFileItem(fileItem.getFilename(), fileItem.getFileType());
        newFileItem.getInode().setFileSize(fileItem.getSize());
        newFileItem.getInode().setUserPermission(fileItem.getUserPermission());
        newFileItem.getInode().setOtherPermission(fileItem.getOtherPermission());
        // 释放新块内容
        for (int index : newFileItem.getInode().fileBlockIndex){
            disk.releaseBlock(index);
        }
        newFileItem.getInode().fileBlockIndex.clear();
        // 拷贝所有文件块内容
        for (int index : fileItem.getInode().getFileBlockIndex()){
            Disk.FileBlock sourceBlock = this.disk.getFileBlock(index);
            int availableBlockIndex = this.disk.getBitmap().getAvailableBlockIndex();
            Disk.FileBlock targetBlock = this.disk.getFileBlock(availableBlockIndex);
            targetBlock.setContent(sourceBlock.getContent(), sourceBlock.getSize());
            newFileItem.getInode().fileBlockIndex.add(availableBlockIndex);
            disk.getBitmap().use(availableBlockIndex);
        }
        return newFileItem;
    }

    /**
     * 获取文件内容
     *
     * @param fileItem 文件对象
     * @return 文件列表, 注意返回的对象仅用于查询,修改操作对源对象无法发生改变
     */
    public List<FileItem> getDirFileContent(FileItem fileItem) {
        // 如果是目录
        if (fileItem.getInode().fileType.equals(Consts.DIR)) {
            // 获取文件块索引
            List<Integer> fileBlockIndex = fileItem.getInode().getFileBlockIndex();
            List<FileItem> result = new ArrayList<FileItem>();
            // 遍历文件块，提取内容
            for (Integer index : fileBlockIndex) {
                Disk.FileBlock fileBlock = disk.getFileBlock(index);
                Object content = fileBlock.getContent();
                // 如果文件块不为空
                if (content != null) {
                    result.addAll((List<FileItem>) content);
                }
            }
            return result;
        } else {
            System.out.println("this is not a directory");
            return null;
        }
    }

    /**
     * 根据名字在目标目录查找文件
     *
     * @param targetDir 目标目录
     * @param filename  文件名
     * @return 查找的文件, 不存在则返回null
     */
    public FileItem findFileByName(FileItem targetDir, String filename) {
        if (targetDir != null && targetDir.getFileType().equals(Consts.DIR)) {
            List<FileItem> dirFileContent = this.getDirFileContent(targetDir);
            // 如果目录没内容
            if (dirFileContent == null) {
                return null;
            } else {
                for (FileItem fileItem : dirFileContent) {
                    if (fileItem.getFilename().equals(filename)) {
                        return fileItem;
                    }
                }
                return null;
            }
        } else {
            logger.warn("your can't find a file in a file");
            return null;
        }
    }

    /**
     * 通过目录路径查找目录
     *
     * @param path 目录路径
     * @return 目录文件, 没有返回null
     */
    public FileItem findFileByPath(String path) {
        if (path.equals(Consts.ROOT_PATH)) {
            return root;
        } else {
            if (path.contains(Consts.ROOT_PATH)) {
                String[] split = path.split("/");
                FileItem current = root;
                for (int i = 1; i < split.length; i++) {
                    FileItem dir = findFileByName(current, split[i]);
                    if (dir == null) {
                        return null;
                    } else {
                        current = dir;
                    }
                }
                return current;
            } else {
                return findFileByName(this.currentDir, path);
            }
        }
    }

    public String findPathByFilename(FileItem targetDir, String filename, String path) {
        List<FileItem> dirFileContent = this.getDirFileContent(targetDir);
        if (dirFileContent == null) {
            return null;
        }
        for (FileItem fileItem : dirFileContent) {
            if (fileItem.getFilename().equals(filename)) {
                Buffer.getInstance().write(path + "/" + filename);
            } else if (!fileItem.getFilename().equals(Consts.CURRENT_DIR) && !fileItem.getFilename().equals(Consts.PARENT_DIR)) {
                if (fileItem.getFileType().equals(Consts.DIR)) {
                    String result = findPathByFilename(fileItem, filename, path + "/" + fileItem.getFilename());
                    if (result != null) {
                        Buffer.getInstance().write(result);
                    }
                }
            }
        }
        if (!"".equals(Buffer.getInstance().getContent())) {
            String result = Buffer.getInstance().getContent();
            Buffer.getInstance().flush();
            return result;
        } else {
            return null;
        }
    }

    /**
     * 在内存中根据文件名查找文件
     *
     * @param filename 文件名
     * @return
     */
    public FileItem findFileInMemory(String filename) {
        for (FileItem fileItem : this.memory) {
            if (fileItem.getFilename().equals(filename)) {
                return fileItem;
            }
        }
        return null;
    }

    public void ls() {
        // 获取缓冲区
        Buffer buffer = Buffer.getInstance();
        List<FileItem> fileContent = getDirFileContent(currentDir);
        // 构造表头
        if (fileContent.size() != 0 && fileContent.size() != 2) {
            String head = String.format("%-10s\t%-5s\t%-5s\t%-5s\t%-10s\t%-12s", "permission", "type", "own", "size",
                    "createTime",
                    "filename");
            buffer.write(head);
        }

        // 构造输出内容
        for (FileItem fileItem : fileContent) {
            if (!fileItem.getFilename().equals(Consts.CURRENT_DIR) && !fileItem.getFilename().equals(Consts.PARENT_DIR)) {
                buffer.write(String.format("%-10s\t%-5s\t%-5s\t%-5s\t%-10s\t%-12s", fileItem.getUserPermission(),
                        fileItem.getFileType(),
                        fileItem.getOwn(),
                        fileItem.getSize(), new SimpleDateFormat(Consts.DATE_FORMAT).format(fileItem.getCreateTime()),
                        fileItem.getFilename()));
            }
        }
    }

    /**
     * 切换目录
     *
     * @param dirname 要切换到的目录名
     */
    public void cd(String dirname) {
        // 判断是否是根目录
        if (!Consts.ROOT_PATH.equals(dirname)) {
            List<FileItem> UFD = getDirFileContent(currentDir);
            for (FileItem fileItem : UFD) {
                if (fileItem.getFilename().equals(dirname)) {
                    if (fileItem.getFileType().equals(Consts.FILE)) {
                        Buffer.getInstance().write("this is not a directory");
                        return;
                    }
                    this.lastDir = this.currentDir;
                    this.currentDir = fileItem;
                    // 如果是返回上级
                    if (Consts.PARENT_DIR.equals(dirname)) {
                        String[] split = this.currentPath.split("/");
                        StringBuilder stringBuilder = new StringBuilder();
                        for (int i = 1; i < split.length - 1; i++) {
                            stringBuilder.append("/").append(split[i]);
                        }
                        if (stringBuilder.toString().length() == 0) {
                            this.currentPath = "/";
                        } else {
                            this.currentPath = stringBuilder.toString();
                        }
                        // 如果当前不是根目录
                    } else if (Consts.CURRENT_DIR.equals(dirname)) {

                    } else if (!"/".equals(this.currentPath)) {
                        this.currentPath += "/" + dirname;
                        // 如果是返回上一级目录
                    } else {
                        this.currentPath += dirname;
                    }
                    return;
                }
            }
            Buffer.getInstance().write("directory not exist");
            // 绝对路径

            // 相对路径
        } else {
            currentDir = root;
            this.currentPath = "/";
        }
    }

    /**
     * 建立目录
     *
     * @param dirname 要创建的目录的名字
     */
    public void mkdir(String dirname) {
        int availableBlockIndex = bitmap.getAvailableBlockIndex();
        if (availableBlockIndex != -1) {
            FileItem newFileItem = this.createNewFileItem(dirname, Consts.DIR);
            this.mountFileItem(this.currentDir, newFileItem, Consts.FILE_ITEM_STD_SIZE);
            // 给新目录挂载"."和".."
            FileItem dot = this.ln(newFileItem, ".");
            FileItem doubleDot = this.ln(this.currentDir, "..");
            this.mountFileItem(newFileItem, dot, dot.getSize());
            this.mountFileItem(newFileItem, doubleDot, doubleDot.getSize());
        } else {
            Buffer.getInstance().write("disk has not enough file block to store!");
        }
    }

    /**
     * 移动文件
     * 1. target中有"/“
     * 1.1 target是文件
     * 在当前目录解除挂载,将source挂载到目录上,修改名字为target中的文件部分
     * 1.2 target是目录
     * 在当前目录解除挂载,将source挂载到target的目录部分
     * 2. target中无"/"
     * 2.1 target 是文件
     * 将文件名字修改为target
     * 2.2 target 是目录
     * 在当前目录解除挂载,将source挂载到target上
     *
     * @param source 源文件
     * @param target 目标文件
     */
    public void mv(String source, String target) {
        if (target.contains("/")) {
            Buffer.getInstance().write("sorry, this function is not complete.");
        } else {
            FileItem sourceFile = this.findFileByName(this.currentDir, source);
            FileItem targetFile = this.findFileByName(this.currentDir, target);
            if (sourceFile == null) {
                Buffer.getInstance().write(source + " not exist!");
            } else {
                // 目标不存在
                if (targetFile == null) {
                    sourceFile.setFilename(target);
                } else {
                    if (targetFile.getFileType().equals(Consts.FILE)) {
                        Buffer.getInstance().write(target + "already exist");
                    } else if (targetFile.getFileType().equals(Consts.DIR)) {
                        this.unmountFileItem(this.currentDir, sourceFile);
                        this.mountFileItem(targetFile, sourceFile, sourceFile.getSize());
                    }
                }
            }
        }
    }


    /**
     * 创建链接文件
     *
     * @param linkedFileItem 被链接的文件
     * @param filename       链接文件名
     * @return 新建的链接文件
     */
    public FileItem ln(FileItem linkedFileItem, String filename) {
        return this.createNewFileItem(filename, linkedFileItem.getInode());
    }

    /**
     * 创建文件
     *
     * @param filename 文件名
     */
    public void touch(String filename) {
        int availableBlockIndex = bitmap.getAvailableBlockIndex();
        if (availableBlockIndex != -1) {
            FileItem newFileItem = this.createNewFileItem(filename, Consts.FILE);
            this.mountFileItem(this.currentDir, newFileItem, Consts.FILE_ITEM_STD_SIZE);
        } else {
            Buffer.getInstance().write("disk has not enough file block to store!");
        }
    }

    /**
     * 删除文件
     *
     * @param filename 文件名
     */
    public void rm(String filename) {
        List<FileItem> dirFileContent = this.getDirFileContent(this.currentDir);
        for (FileItem fileItem : dirFileContent) {
            if (filename.equals(fileItem.getFilename())) {
                if (fileItem.getFileType().equals(Consts.FILE)) {
                    this.unmountFileItem(this.currentDir, fileItem);
                } else {
                    Buffer.getInstance().write("this is a directory,please use \"rmdir\" to delete");
                }
                return;
            }
        }
        Buffer.getInstance().write("file not exist");
    }

    public void rmdir(String dirname) {
        // 判断是否是根目录
        if (!Consts.ROOT_PATH.equals(dirname)) {
            List<FileItem> dirFileContent = this.getDirFileContent(this.currentDir);
            for (FileItem fileItem : dirFileContent) {
                if (dirname.equals(fileItem.getFilename())) {
                    if (fileItem.getFileType().equals(Consts.DIR)) {
                        this.unmountFileItem(this.currentDir, fileItem);
                    } else {
                        Buffer.getInstance().write("this is a file,please use \"rm\" to delete");
                    }
                    return;
                }
            }
            Buffer.getInstance().write("no such directory");
        } else {
            Buffer.getInstance().write("wtf? you can't do it");
        }
    }

    /**
     * 在目标目录中查找文件
     *
     * @param targetDir 目标目录
     * @param filename  查找的文件名
     */
    public void find(String targetDir, String filename) {
        FileItem dir = this.findFileByPath(targetDir);
        // 如果是相对路径查找
        FileItem fileByName = this.findFileByName(this.currentDir, targetDir);
        String path = targetDir;
        if (fileByName != null) {
            path = this.currentPath + "/" + targetDir;
        } else if (targetDir.equals(Consts.ROOT_PATH)) {
            path = "";
        }
        if (dir == null) {
            Buffer.getInstance().write("target Directory is not exist");
        } else {
            path = this.findPathByFilename(dir, filename, path);
            if (path == null) {
                Buffer.getInstance().write("file \"" + filename + "\" not exist");
            } else {
                Buffer.getInstance().write(path);
            }
        }
    }

    /**
     * 打开文件
     *
     * @param filename 文件名
     */
    public void open(String filename) {
        FileItem fileByName = this.findFileByName(this.currentDir, filename);
        // 查找文件是否存在
        if (fileByName == null) {
            Buffer.getInstance().write("file " + filename + " not exist");
        } else {
            // 判断是否已经在内存中
            FileItem fileInMemory = this.findFileInMemory(filename);
            if (fileInMemory != null) {
                Buffer.getInstance().write("the file is already opened");
                return;
            }
            // 判断内存是否充足
            if (this.memory.size() == this.memorySize) {
                Buffer.getInstance().write("Memory overflow, please close some file");
                Buffer.getInstance().write("now opened file:");
                for (FileItem fileItem : this.memory) {
                    Buffer.getInstance().write("- " + fileItem.getFilename());
                }
                return;
            }
            //判断是否是文件
            if (fileByName.getFileType().equals(Consts.FILE)) {
                this.memory.add(fileByName);
                Buffer.getInstance().write("ok");
            } else {
                Buffer.getInstance().write("you can't open a directory");
            }
        }
    }

    /**
     * 写入文件内容
     *
     * @param filename 文件名
     */
    public void write(String filename) {
        FileItem fileByName = this.findFileByName(this.currentDir, filename);
        // 查找文件是否存在
        if (fileByName == null) {
            Buffer.getInstance().write("file " + filename + " not exist");
        } else {
            //判断是否是文件
            if (fileByName.getFileType().equals(Consts.FILE)) {
                if (this.memory.contains(fileByName)) {
                    // 这里是因为后续的修改文件会导致无法查找
                    this.memory.remove(fileByName);
                    System.out.println("please input you content and end with \"#end\":");
                    Scanner scanner = new Scanner(System.in);
                    StringBuilder stringBuilder = new StringBuilder();
                    while (true) {
                        String s = scanner.nextLine();
                        if ("#end".equals(s)) {
                            break;
                        }
                        stringBuilder.append(s).append("\n");
                    }
                    stringBuilder.deleteCharAt(stringBuilder.length() - 1);
                    // 将文件原来内容删除
                    rm(filename);
                    touch(filename);
                    fileByName = this.findFileByName(this.currentDir, filename);
                    int lastBlockIndex = fileByName.getInode().getLastBlockIndex();
                    Disk.FileBlock fileBlock = disk.getFileBlock(lastBlockIndex);
                    fileBlock.setContent(stringBuilder.toString(), stringBuilder.toString().length());
                    this.memory.add(fileByName);
                    Buffer.getInstance().write("ok, file is saved");
                } else {
                    Buffer.getInstance().write("please open the file first");
                }
            } else {
                Buffer.getInstance().write("you can't write content into a directory");
            }
        }
    }

    /**
     * 读取文件
     *
     * @param filename 文件名
     */
    public void read(String filename) {
        FileItem fileByName = this.findFileByName(this.currentDir, filename);
        // 查找文件是否存在
        if (fileByName == null) {
            Buffer.getInstance().write("file " + filename + " not exist");
        } else {
            //判断是否是文件
            if (fileByName.getFileType().equals(Consts.FILE)) {
                if (this.memory.contains(fileByName)) {
                    List<Integer> fileBlockIndex = fileByName.getInode().getFileBlockIndex();
                    for (Integer i : fileBlockIndex) {
                        Disk.FileBlock fileBlock = disk.getFileBlock(i);
                        Buffer.getInstance().write((String) fileBlock.getContent());
                    }
                } else {
                    Buffer.getInstance().write("please open the file first");
                }
            }else {
                Buffer.getInstance().write("you can't open a directory");
            }
        }
    }

    public void close(String filename) {
        FileItem fileByName = this.findFileInMemory(filename);
        // 查找文件是否存在
        if (fileByName == null) {
            Buffer.getInstance().write("file " + filename + " not opened");
        } else {
            this.memory.remove(fileByName);
            Buffer.getInstance().write("ok");
        }
    }

    public void copy(String source, String target){
        FileItem sourceFile = this.findFileByName(this.currentDir, source);
        if (sourceFile == null){
            Buffer.getInstance().write("source file not exist");
            return;
        }else if (sourceFile.getFileType().equals(Consts.DIR)){
            Buffer.getInstance().write("sorry, this function has been not finished.");
            return;
        }
        FileItem targetDir = this.findFileByPath(target);
        if (targetDir == null){
            Buffer.getInstance().write("target directory is not exist");
        }else if(targetDir.getFileType().equals(Consts.FILE)){
            Buffer.getInstance().write("you only can copy a file to a directory");
        }else {
            FileItem fileItem = this.copyFileItem(sourceFile);
            this.mountFileItem(targetDir, fileItem, fileItem.getSize());
        }
    }

    public void exit() {
        System.out.println("bye~!");
        Disk.drop(disk);
        System.exit(0);
    }

    public void run() {
        printWelcome();

        while (true) {
            if (login()) {
                while (true) {
                    printHint();
                    String commands = CommandUtils.readCommand();
                    if (!"".equals(commands)) {
                        String command = CommandUtils.getCommand(commands);
                        String[] params = CommandUtils.getParams(commands);
                        CommandUtils.executeCommand(this, command, params);
                        Buffer.getInstance().output();
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        FileSystem fileSystem = new FileSystem();
        fileSystem.run();
    }
}
